package com.example.controller;
/**
 * 用于演示 :
 *
 * @author : gao'm
 */
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.example.pojo.entity.Orders;
import com.example.service.AlipayService;
import com.example.service.OrderInfoService;
import com.example.task.AlipayTask;
import com.example.vo.Result;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("alipays")
public class AlipayController {

    @Autowired
    private AlipayTask alipayTask;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private Environment config;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("pay/{id}")
    public Result tradePagePay(@PathVariable("id") Integer resuId, HttpServletRequest request){
        Integer jsId = request.getIntHeader("id");
        System.out.println("=获取id=");
        System.out.println(jsId);
//        支付宝接受请求后返回html形式的表单(响应形式)
//        System.out.println(resuId);
        String formStr = alipayService.tradeCreate(resuId,jsId);
        System.out.println("==支付==");
        System.out.println(formStr);
//        前端将form表单自动提交到支付宝->展示支付页面
        return new Result(200,"支付成功",formStr);
    }

//    通知接口,用于支付成功的异步通知
    @PostMapping("notify")
    public String tradeNotify(@RequestParam Map<String,String> params){
        log.info("支付异步通知");
        System.out.println("===================================");

        String result = "failure";

//        异步通知验签
        //将异步通知中收到的所有参数都存放到map中
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, config.getProperty("alipay.alipay-public-key"), "UTF-8", "RSA2");

            if(!signVerified){
                //验签失败则记录异常日志，并在response中返回failure.
                log.error("异步验签失败");
                return result;
            }
            //验签成功,按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验 - 四项条件有任何一个验证不通过，则表明本次通知是异常通知，务必忽略
//            1. 商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号
            String ordTradeNo1 = params.get("out_trade_no");
            Long ordTradeNo = Long.parseLong(ordTradeNo1);
            Orders orders = orderInfoService.getOrdbyOrdNum(ordTradeNo);
            if (orders == null){
                log.error("订单不存在!!!");
                return result;
            }

//           2. 判断 total_amount 是否确实为该订单的实际金额（即商家订单创建时的金额）
            String total = params.get("total_amount");
            System.out.println(total+":===>");
            int totalAmount = new BigDecimal(total).multiply(new BigDecimal("1")).intValue();

            int totalFee = orders.getOrdTotalFee().intValue();
            System.out.println(totalAmount+"<:>"+totalFee);
            if (totalAmount != totalFee){
                log.error("金额校验失败!!!");
                return result;
            }

//            3. 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方（有的时候，一个商家可能有多个 seller_id/seller_email）
            String sellerId = params.get("seller_id");
            String sellerIdProperty = config.getProperty("alipay.seller-id");
            if (!sellerId.equals(sellerIdProperty)){
                log.error("商户pid校验失败!!!");
                return result;
            }

//              4. 验证 app_id 是否为该商家本身
            String appId = params.get("app_id");
            String appIdProperty = config.getProperty("alipay.app-id");
            if (!appId.equals(appIdProperty)){
                log.error("appId校验失败!!!");
                return result;
            }

//            只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功
            String tradeStatus = params.get("trade_status");
            System.out.println(tradeStatus);
            if (!"TRADE_SUCCESS".equals(tradeStatus) & !"TRADE_FINISHED".equals(tradeStatus)){
                log.error("支付未成功!!!");
                return result;
            }
            // 校验成功,在response中返回success并继续商户自身业务处理，校验失败返回failure
//            TODO...继续处理自身业务 修改订单支付状态 记录支付日志
            alipayService.processOrder(params);

            result = "success";

        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }

    @PostMapping("close/{ordNum}")
    public Result cancel(@PathVariable String ordNum){
        log.info("取消订单");
        alipayService.cancelOrder(ordNum);
        return new Result(200,"取消成功");
    }

//    主动查询支付
@GetMapping("query/{ordNum}")
public Result queryOrder(@PathVariable String ordNum){
    log.info("查询订单");

    String result = alipayService.queryOrder(ordNum);
    return new Result(200,"查询成功",result);
}

//确认未支付订单状态
    @PostMapping("check/{jsId}")
    public Result checkOrder(@PathVariable Integer jsId){
        log.info("查询订单");
        String result = null;
        List<Orders> ordersList = orderInfoService.getByJsId(jsId);
        if (ordersList!=null){
            for (Orders o : ordersList) {
                alipayService.checkOrdStatus(o.getOrdNumber());
            }
            result = "查询成功";
        }
        return new Result(200,"查询成功",result);
    }

    @PostMapping("refund/{name}/{jsId}")
    public Result refund(@PathVariable("name") String name,@PathVariable("jsId") Integer jsId){
        log.info("订单退款处理");
        String ordNum = orderInfoService.getByOrdTitleAndJsId(name,jsId);
        if (ordNum==null){
            System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
            String message = null;
            return new Result(200,"无可退款",message);
        }
        alipayService.refund(ordNum);
        String message = "退款成功";
        System.out.println("bbbbbbbbbbbbbbbbbbbbbbbbbbb");
        return new Result(200,"退款成功",message);
    }

//    主动查询退款
    @GetMapping("queryrefund/{ordNum}")
    public Result queryRefund(@PathVariable String ordNum){
        log.info("查询订单");

        String result = alipayService.queryRefund(ordNum);
        return new Result(200,"查询成功",result);
    }


    @PostMapping("task")
    public void task(@RequestHeader("id") Integer id){
        ValueOperations vop = redisTemplate.opsForValue();
        vop.set("AliTime"+id,String.valueOf(System.currentTimeMillis()));
        System.out.println("==获取id==");
        System.out.println(id);
        alipayTask.orderConfirm(id);
    }
}

